package com.mdjukebox.services.dj.player;

import java.io.File;
import java.io.IOException;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import javazoom.jlgui.basicplayer.BasicController;
import javazoom.jlgui.basicplayer.BasicPlayer;
import javazoom.jlgui.basicplayer.BasicPlayerEvent;
import javazoom.jlgui.basicplayer.BasicPlayerException;
import javazoom.jlgui.basicplayer.BasicPlayerListener;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.mdjukebox.model.jukeboxfacade.actions.AutomaticoAction;
import com.mdjukebox.model.vo.CancionVO;
import com.util.exceptions.InternalErrorException;
import com.util.exceptions.ModelException;
import com.util.sql.PlainActionProcessor;

public class Reproductor extends HttpServlet implements BasicPlayerListener
{
	private static final long serialVersionUID = 4470414495805629240L;
	private static final Log log = LogFactory.getLog(Reproductor.class);
	private BasicController control;
	private static String basicPathMusic = "";
	private boolean reproducir = false;
	
    public void init()
    {
		try
		{
			basicPathMusic = this.getInitParameter("basicPathMusic");
			
			BasicPlayer player = new BasicPlayer();
			control = (BasicController) player;
			player.addBasicPlayerListener(this);
			playNextSong();
		}
		catch (Exception e)
		{
			display("EXCEPCION --> " + e.getMessage());
		}

    }
    
   
    public void doGet(HttpServletRequest request, HttpServletResponse response)
    	throws IOException, ServletException {
    	try{
	    	/* accion */
    		display("Reproductor-----");
	        String accion = request.getParameter("acc");
	        if ("stop".equals(accion)){
	        	parar();
	        	if (log.isDebugEnabled()) log.debug("---------- Reproduccion Parado");
	        	request.setAttribute("msg", "Stop.OK");
	        }else if ("play".equals(accion)){
	        	rearrancar();
	        	if (log.isDebugEnabled()) log.debug("---------- Reproduccion Rearrancada");
	        	request.setAttribute("msg", "Play.OK");
	        }else if ("state".equals(accion)){
	        	if (reproducir)
	        		request.setAttribute("msg", "State.Play");
	        	else
	        		request.setAttribute("msg", "State.Stop");
	        }else{
	        	request.setAttribute("msg", "Error.ParamNotValid");
	        }
	        
	        
	        
	        //display("FORWARD " + response.encodeRedirectURL("/mensajes.do"));
	        getServletConfig().getServletContext().getRequestDispatcher("/mensajes.do").forward(request, response);
    	}catch(Exception e){
    		display("EXCEPCION --> " + e.getMessage());
    	}
    }
    
    /*
     * Funciona si 
     * request.getSession(true).setAttribute("msg", "Reproduciendo");
     * response.sendRedirect("/mdjukebox/mensajes.do");
     * <c:out value="${msg}"/>
     * 
     * 
     * */
    
    public void doPost(HttpServletRequest request, HttpServletResponse response)
		throws IOException, ServletException {
		
		doGet(request, response);
		
	}
    
    public synchronized void parar(){
    	this.reproducir = false;
    }
    
    public synchronized void rearrancar(){
    	this.reproducir = true;
    	playNextSong();
    }
    
	private void playNextSong()
	{
		display("NEXT SONG");

		if(reproducir){
		try
		{
			//TODO Pb bucle infinito
			File nextsong = null;
			while (nextsong==null){
				nextsong = getNextSong();
				if (!nextsong.exists()){
					if (log.isWarnEnabled()) log.warn("Fichero "+nextsong.getAbsolutePath() + " no existe");
					nextsong=null;
				}
			}
			control.open(nextsong);
			control.play();
			control.setGain(0.85);
			control.setPan(0.0);
		}
		catch (BasicPlayerException e)
		{
			display("EXCEPCION --> " + e.getMessage());
		}
		}else{
			display("REPRODUCCION PARADA");
		}
	}
	private File getNextSong()
	{
		AutomaticoAction automaticoAction = new AutomaticoAction();
		File nextSong = null;
		try
		{
			CancionVO cancionVO = (CancionVO)PlainActionProcessor.process(automaticoAction);
			String file = basicPathMusic + cancionVO.getPath();
            display("Reproductor: " + file);
			nextSong = new File(file);
		}
		catch (ModelException e)
		{
			if (log.isDebugEnabled()) log.debug("Next Song: ", e);
		} 
		catch (InternalErrorException e) 
		{
			if (log.isDebugEnabled()) log.debug("Next Song: ", e);
		}catch (Exception e){			
			if (log.isDebugEnabled()) log.debug("Next Song: ", e);
		}
		return nextSong;
	}
	public void opened(Object stream, Map properties)
	{
		display("opened : "+properties.toString());		
	}

	public void progress(int bytesread, long microseconds, byte[] pcmdata, Map properties)
	{
	}


	public void stateUpdated(BasicPlayerEvent event)
	{
		display("stateUpdated : "+event.toString());
		if (event.getCode()==BasicPlayerEvent.EOM)
		{
			playNextSong();
		}
	}
	public void setController(BasicController controller)
	{
		display("setController : "+controller);
	}
	
	public void display(String msg)
	{
		if (log.isDebugEnabled()) log.debug(msg);
	}
}
